#include <iostream>
#include <sys/types.h>
#include <semaphore.h>
#include <vector>
#include "before_task.h"
#include <string>
#include <ctime>
#include <unistd.h>
using namespace std;

#define QUEUESIZE 10

template <class T>
class circleQueue
{
public:
    circleQueue()
    {
        sem_init(&_space_sem, 0, QUEUESIZE);
        sem_init(&_data_sem, 0, 0);
        _q.resize(QUEUESIZE); // 初始化容器大小，使得下面进行数据增删不会发生越界
    }

    void p(sem_t &sem) // 也就是--操作
    {
        sem_wait(&sem);
    }

    void v(sem_t &sem) //++操作
    {
        sem_post(&sem);
    }

    void push(const T &task)
    {
        p(_space_sem);
        _p_pos %= QUEUESIZE;
        _q[_p_pos] = task;
        _p_pos++;
        _size++;

        v(_data_sem);
    }

    T pop()
    {
        p(_data_sem);
        _c_pos %= QUEUESIZE;
        T task = _q[_c_pos];
        _c_pos++;
        _size--;
        v(_space_sem);
        return task;
    }

    int size()
    {
        return _size;
    }

private:
    sem_t _space_sem; // 位置的信号量
    sem_t _data_sem;  // 数据的信号量
    T _task;          // 这个循环队列中装载的数据类型
    vector<T> _q;     // 真正的装载数据的容器

    int _p_pos = 0; // 生产者生产数据的位置
    int _c_pos = 0; // 消费者消数据的位置
    int _size = 0;
};

struct threadData
{
    threadData(int num) : threadname("thrad-" + to_string(num))
    {
    }
    string threadname;

    circleQueue<task> q;
};

void *consumer(void *args)
{
    threadData *data = static_cast<threadData *>(args);
}

void *producer(void *args)
{
    threadData *data = static_cast<threadData *>(args);
    // 开始生产任务
    int x = rand() % 10 + 1;
    usleep(10);
    int y = rand() % 5;
    char op = opr[rand() % 5];
    task t(x, y, op);

    while (true)
    {
        
    }
}

int main()
{
    srand(time(nullptr));
    circleQueue<task> q;
    pthread_t c_tid;
    pthread_t p_tid;

    threadData *d1 = new threadData(1);
    threadData *d2 = new threadData(1);
    pthread_create(&c_tid, nullptr, consumer, d1);
    pthread_create(&c_tid, nullptr, producer, d2);

    void *ret;
    pthread_join(c_tid, &ret);
    pthread_join(p_tid, &ret);

    return 0;
}